<?php
namespace app\api;

class ApiBaseController
{
    protected $user_id = 0;

    //无需登录就可以用的接口（空数组代表都不需要登录）（剩下的接口都必须要登录）
    protected $ignoreLogin = [
        'user'=>[
            'login',
        ],
    ];

    /**
     * Api constructor.
     * @throws \Exception
     */
    public function __construct()
    {
        //$module = request()->module();
        $controller = strtolower(request()->controller());
        $action = strtolower(request()->action());

        //拿到用户id
        $token = request()->header('token');
        $token and $this->user_id = $this->decryptToken($token);

        if ($this->ignoreLogin) {
            if (!isset($this->ignoreLogin[$controller])) {
                $this->auth();
            } elseif ($this->ignoreLogin[$controller] && !in_array($action, $this->ignoreLogin[$controller])) {
                $this->auth();
            }
        }
    }

    /**
     * 检测是否登录
     * @throws \Exception
     */
    protected function auth()
    {
        if (empty($this->user_id)) {
            throw new \Exception('请重新登录', 401);
        }
    }

    protected function getUserInfo()
    {
        static $userInfo;
        if (empty($userInfo) && $this->user_id) {
            $userInfo = \app\common\model\UserModel::get($this->user_id);
        }
        return $userInfo;
    }

    /**
     * @explain 获取post和get
     * @param $key
     * @param string $type 数据类型，支持int,float和默认的str
     * @param string $default 默认值
     * @return float|int|string
     * @throws \Exception
     */
    protected function input($key, $type = 'str', $default = '')
    {
        static $input;
        if (empty($input)) {
            $input = request()->put();//post了raw的json字符串过来的话
            if (empty($input)) {
                $input = request()->post();
            }
            $input = array_merge($input, request()->get());
        }

        $value = isset($input[$key]) ? $input[$key] : '';

        if (is_array($value)) {
            return $value;
        }

        $value = trim($value);
        //默认值
        if ($value === '' && !empty($default)) {
            $value = $default;
        }

        //担心前端JS没控制好
        if ($value === 'undefined' || $value === 'null') {
            if (config('app_debug')) {//调试模式直接报错
                throw new \Exception('参数错误', 400);
            } else {
                trace('参数为undefined或null', 'error');//记下错误日志
                $value = '';
            }
        }

        //修饰
        if ($type == 'str') {
            $value = strval($value);
        } elseif ($type == 'int') {
            $value = intval($value);
        } elseif ($type == 'float') {
            $value = floatval($value);
        }
        return $value;
    }

    /**
     * @explain 检查参数是否为空
     * @param mixed $data
     * @param bool $cannot_be_zero 默认可以是0，如果确定参数为0是错误的话可以设为true
     * @throws \Exception
     */
    protected function checkParams($data, $cannot_be_zero = false)
    {
        if (is_array($data)) {
            foreach ($data as $value) {
                if ($cannot_be_zero) {
                    if (empty($value)) {
                        throw new \Exception('参数错误', 400);
                    }
                } else {
                    if ($value === '' || $value === null) {
                        throw new \Exception('参数错误', 400);
                    }
                }
            }
        } else {
            if ($cannot_be_zero) {
                if (empty($data)) {
                    throw new \Exception('参数错误', 400);
                }
            } else {
                if ($data === '' || $data === null) {
                    throw new \Exception('参数错误', 400);
                }
            }
        }
    }

    /**
     * @explain 用于处理正常输出
     * @param $data
     * @param string $msg
     */
    protected function output($data = [], $msg = null)
    {
        $this->output_json($data, 0, $msg);
    }

    /**
     * @explain 用于处理异常输出
     * @param $exception
     * @param string $msg 替换exception的msg
     */
    protected function exception(\Exception $exception, $msg = '')
    {
        $output = exception_handle($exception);
        $msg and $output['message'] = $msg;
        out_json($output);
    }

    /**
     * 统一输出JSON
     * @param array  $data json中data的内容
     * @param int    $code 通知码,默认0
     * @param string $msg 通知信息,默认ok
     */
    protected function output_json($data = array(), $code = 0, $msg = null)
    {
        $output = [
            'code' => intval($code),
            'message' => is_null($msg) ? 'OK' : $msg,
            'data' => $data,
        ];
        out_json($output);
    }

    /**
     * @explain 加密用户ID（以后可加有效时间）
     * @param $id
     * @return mixed
     */
    protected function encryptToken($id)
    {
        $key = 'hjh';
        return authcode($id, 'ENCODE', $key);
    }

    /**
     * @explain 解密用户ID
     * @param $token
     * @return mixed
     */
    protected function decryptToken($token)
    {
        $key = 'hjh';
        return authcode($token, 'DECODE', $key);
    }
}
